#include "mainsourceupdate.h"

MainSourceUpdate::MainSourceUpdate(QObject *parent) : QObject(parent)
{

}

bool MainSourceUpdate::checkUpdateInit()
{
    bool ret = true;

    /*更新之前清空之前的推送列表*/
    readyForUpdate();
    if (!liveCDSourceIsExist()) {
        qDebug() << "光盘源不存在，在线检测更新";
        for (int var = 0; var < serverInfoList.size(); var++) {
            qDebug() << "访问第" << var + 1 << "个服务器，总计有" << serverInfoList.size();
            serverHost = serverInfoList.at(var).address;
            serverPort = serverInfoList.at(var).port;
            ret = getUpdateTransaction(var);
            if (!ret) {
                QSettings set("/var/lib/kylin-software-properties/data/request.info", QSettings::IniFormat);
                if (set.value("Time/lasetRequsetTime").toString() == ""){
                    ret = getSourceInfoFromServer(var);
                }
            }
            if (ret)
                break;
        }
    }
    if (ret)
        sendUpdateTemplateSignal("success");
    else
        sendUpdateTemplateSignal("");
    return ret;
}
/*
 * 判断光盘源是否存在，如果存在光盘源模板直接替换主源更新
*/
bool MainSourceUpdate::liveCDSourceIsExist()
{
    QDir dir("/media/");
    if (!dir.exists()) {
        qDebug() << "media 目录不存在";
        return false;
    }
    bool haveCDrom = false;
    /*过滤 只要目录文件不包括./和../*/
    dir.setFilter(QDir::Dirs  | QDir::NoDotAndDotDot);
    QFileInfoList list = dir.entryInfoList();
    QString filename;
    QString filename2;
    foreach (QFileInfo info, list) {
        filename.clear();
        filename.append(info.fileName());
        QDir dir2("/media/" + filename);
        dir2.setFilter(QDir::Dirs  | QDir::NoDotAndDotDot);
        QFileInfoList list2 = dir2.entryInfoList();
        foreach (QFileInfo info, list2) {
            haveCDrom = false;
            filename2.clear();
            filename2.append(info.fileName());
            QFile file("/media/" + filename + "/" + filename2 + "/ss.map");
            if (file.exists()) {
                haveCDrom = true;
                break;
            } else {
                filename2.clear();
            }
        }
        if (haveCDrom)
            break;
    }
    qDebug() <<"filename2:" << filename2;
    if (filename2.isNull()) {
        return false;
    }

    QString updaterVersion = getPkgVersionFromPkgName("kylin-system-updater");

    QString sourcelistPath = "";

    if (updaterVersion >= "2.0.5.16-0k6.0"){
        QDir dir1("/var/lib/kylin-system-updater/");
        if (!dir1.exists()){
            dir1.mkdir("/var/lib/kylin-system-updater/");
        }
        sourcelistPath = "/var/lib/kylin-system-updater/sources.list";
    }else {
        QDir dir1("/etc/apt/");
        if (!dir1.exists()){
            dir1.mkdir("/etc/apt/");
        }
        sourcelistPath = "/etc/apt/sources.list";
    }
    /*找到光盘路径后替换sources.list文件*/
    QDir dir1("/var/lib/kylin-system-updater/");
    if (!dir1.exists()){
        dir1.mkdir("/var/lib/kylin-system-updater/");
    }
    QFile fileModify(sourcelistPath);
    if (!fileModify.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
        qDebug() <<  sourcelistPath <<" 打开失败！" << fileModify.errorString();
    }
    QTextStream out(&fileModify);


    //存在光盘源，获取是否存在policy文件
    QDir Dir("/media/" + filename + "/" + filename2);
    if (Dir.exists()) {
        Dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);
        QFileInfoList List = Dir.entryInfoList();
        qDebug() << "list==" << list;
        foreach (QFileInfo Info, List) {
            QDir v2Dir("/media/" + filename + "/" + filename2 + "/" + Info.fileName() + "/v2.1/");
            QDir distDir("/media/" + filename + "/" + filename2 + "/" + Info.fileName() + "/dists/");
            //如果有2.1目录走新逻辑
            if (v2Dir.exists()){
                //读取policy json
                QFile jsonFile("/media/" + filename + "/" + filename2 + "/" + Info.fileName() + "/v2.1/policy/policy.json");
                //                QFile jsonFile("/home/wanghailiang/policy.json");
                if (!jsonFile.exists()){
                    qDebug() << "光盘源中策略文件不存在";
                    return false;
                }
                //转化为json
                qDebug() <<"存在新光盘源";
                QJsonObject policyObj;
                QJsonParseError jsonerror;
                if (jsonFile.open(QIODevice::ReadOnly)){
                    QJsonDocument doc = QJsonDocument::fromJson(jsonFile.readAll(),&jsonerror);
                    //                    qDebug() << doc.object();
                    if (!doc.isNull() && (jsonerror.error == QJsonParseError::NoError)) {
                        if (doc.isObject()) {
                            policyObj = doc.object();
                            readUpdateTransaction(policyObj, "/media/" + filename + "/" + filename2 + "/" + Info.fileName()+ "/v2.1/dists/");
                        }
                    }else {
                        qDebug() <<"未读取到json或者json解析错误" << jsonerror.errorString();
                    }
                }
            }else if (distDir.exists()){
                qDebug() <<"存在旧光盘源";
                //有dists目录没有v2.1走旧目录
                distDir.setFilter(QDir::Dirs  | QDir::NoDotAndDotDot);
                QFileInfoList distList = distDir.entryInfoList();
                foreach (QFileInfo distStr, distList) {
                    QDir branchDir(distStr.filePath());
                    if (branchDir.exists()) {
                        branchDir.setFilter(QDir::Dirs  | QDir::NoDotAndDotDot);
                        QFileInfoList branchList = branchDir.entryInfoList();
                        QString src;
                        src = "deb file:///media/" + filename +"/" + filename2 + "/" + Info.fileName() + " " + distStr.fileName();
                        foreach (QFileInfo branchStr, branchList) {
                            src.append(" ");
                            src.append(branchStr.fileName());
                            QString crucialPath = "/media/" + filename + "/" + filename2 + "/" + Info.fileName() + "/dists/" + \
                                    distStr.fileName() + "/" + branchStr.fileName();
                            m_ImportantList  << crucialPath;
                        }
                        out << src << "\n";
                    }
                }
                writeCDSourcePkgList();
            }else {
                //没有的话，就是光盘源不存在，直接返回
                return false;
            }

        }
    }

    return true;
}
/*
 * 写入光盘源更新包列表
*/
void MainSourceUpdate::writeCDSourcePkgList()
{
    /*判断目录是否存在，不存在则创建*/
    QDir templateDir(TEMPLATE_FILE_PATH);
    if (!templateDir.exists()) {
        templateDir.mkpath(TEMPLATE_FILE_PATH);
    }

    QFile crucialFile(CRUCIAL_FILE_PATH);
    if (!crucialFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
        qDebug() << CRUCIAL_FILE_PATH << "open failed!";
    }
    QTextStream crucialStream(&crucialFile);
    crucialStream << "";
    crucialFile.flush();
    crucialFile.close();

    QFile importFile(IMPORTANT_FILE_PATH);
    if (!importFile.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
        qDebug() << IMPORTANT_FILE_PATH << "open failed!";
    }
    QTextStream importantStream(&importFile);

    foreach (QString str, m_ImportantList) {
        str.append("/important.list");
        QFile file(str);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            qDebug() << str << "open failed!";
            importFile.close();
            return ;
        }
        QString packageList = QString(file.readAll());
        importantStream << " " << packageList;
    }
    importantStream.flush();
    importFile.close();
    return ;
}

/*
 * 更新前准备
*/
void MainSourceUpdate::readyForUpdate()
{
    /*清空之前缓存*/
    serverInfoList.clear();
    m_systemVersion = "";
    m_patchVersion = "";
    m_cpu = "";
    m_lastRequesetAt = "";
    enableExperiencePlan = false;
    m_uuidIsUpload = false;
    m_ImportantList.clear();
    qDebug() << "判断文件是否存在，如果不存在拷贝";
    /*获取服务器地址*/
    /*判断文件是否存在，如果不存在则从/usr/share/kylin-software-properties/template/kylin-source-update.conf 复制过去*/
    QFile file(CONF_FILE_PATH);
    if (!file.exists()) {
        QProcess pro;
        QString shell;
        QFile file1(TEMPLATE_FILE_PATH);
        if (!file1.exists()) {
            QDir *dir = new QDir();
            dir->mkpath(TEMPLATE_FILE_PATH);
            shell.append("cp -r ");
            shell.append(TEMPLATE_FILE_PATH);
            shell.append(" ");
            shell.append(KYLIN_SOFTWARE_PROPERTIES_PATH);
            delete dir;
        } else {
            shell.append("cp ");
            shell.append(KYLIN_SOURCE_UPDATE_CONF);
            shell.append(" ");
            shell.append(CONF_FILE_PATH);
        }
        pro.start(shell);
        pro.waitForFinished(-1);
        pro.close();
    }
    setServerAddressPriority();
    /*获取系统版本补丁版本*/
    getSystemVersionAndPatchVersion();
    qDebug() << "systemVersion"<<m_systemVersion << "patchVersion" << m_patchVersion;

    //获取是否启动体验计划
    QSettings set("/var/lib/kylin-software-properties/config/updateExperience.conf", QSettings::IniFormat);
    if (!set.value("Experience/isUpdateExperience").toString().compare("true")){
        enableExperiencePlan = true;
    }
    qDebug()<< "获取体验计划是否开启" << enableExperiencePlan;
    //获取CPU信息
    getCpuInfo();
    getLastRequestAtTime();
    getProductLine();
    qDebug() << "m_productline " <<m_productLine << m_arch;
    //获取其他信息
    QProcess process;
    process.start("bash /var/lib/kylin-software-properties/script/getInfo");
    process.waitForReadyRead(-1);
    QString jsonStr =  QString(process.readAllStandardOutput());
    process.waitForFinished(-1);
    process.close();
    \
    qDebug() << "jsonStr === " << jsonStr;
    QJsonDocument jsonDocument = QJsonDocument::fromJson(jsonStr.toLocal8Bit().data());
    if(jsonDocument.isNull()){
        qDebug()<< "===> please check the string "<< jsonStr.toLocal8Bit().data();
    }
    QJsonObject jsonObject = jsonDocument.object();
    m_ip = jsonObject.value("ip").toString().remove("\n").remove("\r");
    m_mac = jsonObject.value("mac").toString().remove("\n").remove("\r");
    m_eqptSn = jsonObject.value("sn").toString().remove("\n").remove("\r");
    m_serverSn = jsonObject.value("serial_number").toString().remove("\n").remove("\r");
    m_activationCode = jsonObject.value("activation").toString().remove("\n").remove("\r");
    m_registerCode = jsonObject.value("register").toString().remove("\n").remove("\r");

    QString historyUid;

    QFile confile("/var/lib/kylin-software-properties/data/upgrade.log");
    if (confile.open(QIODevice::ReadOnly)){
        QByteArray tmp =  confile.readAll();
        historyUid = QString::fromUtf8(tmp);
    }
    /*获取上次更新的UUID记录在配置文件中*/
    QSettings updaterSet("/var/lib/kylin-system-updater/system-updater.conf", QSettings::IniFormat);
    QString lastUpdateStatus = updaterSet.value("statusForProperties/last_install").toString();
    QString lastUuid = updaterSet.value("statusForProperties/uuid").toString();

    if (!lastUpdateStatus.compare("success")){
        qDebug() << "uuid更新成功:" << lastUuid;
        QFile confile("/var/lib/kylin-software-properties/data/upgrade.log");
        if (confile.open(QIODevice::ReadWrite | QIODevice::Append)){
            if (!historyUid.contains(lastUuid)){
                QTextStream confStream(&confile);
                confStream << lastUuid << "\n";
                confile.flush();
                confile.close();
            }else
                confile.close();
        }
    }
}
/*
 * 设置源服务器地址的优先级
*/
void MainSourceUpdate::setServerAddressPriority()
{

    QSettings settingsread(CONF_FILE_PATH,QSettings::IniFormat);

    QStringList groupList =  settingsread.childGroups();
    foreach (QString str, groupList) {
        serverInfo info;
        info.address = settingsread.value(str + "/Address").toString();
        info.port = settingsread.value(str + "/Port").toInt();
        info.priority = settingsread.value(str + "/Priority").toInt();
        serverInfoList.append(info);
    }
    if (serverInfoList.size() == 0){
        serverInfo info;
        info.address = "http://archive1.kylinos.cn";
        info.port = 59546;
        info.priority = 1000;
        serverInfoList.append(info);
    }

    // < 从小到大 > 从大到小
    qSort(serverInfoList.begin(), serverInfoList.end(),[](const serverInfo &infoA,const serverInfo &infoB) {
        return infoA.priority > infoB.priority;
    });
    return ;
}
/*
 * 获取更新事务
*/
bool MainSourceUpdate::getUpdateTransaction(int var)
{
    bool ret = false;
    //获取服务器地址
    QString address = serverInfoList.at(var).address;
    QString port = QString::number(serverInfoList.at(var).port);

    //构建URL
    QString urlStr = "";
    if (!port.compare("")){
        urlStr = address + "/transaction/list";
    } else {
        urlStr = address + ":" + port + "/transaction/list";
    }

    qDebug() << "地址："<< urlStr;
    //设置参数
    QUrl url(urlStr);
    QUrlQuery query;
    query.addQueryItem("mac",QString(QUrl::toPercentEncoding(m_mac)));
    query.addQueryItem("ip",QString(QUrl::toPercentEncoding(m_ip)));
    query.addQueryItem("eqptSn",QString(QUrl::toPercentEncoding(m_eqptSn)));
    query.addQueryItem("serverSn",QString(QUrl::toPercentEncoding(m_serverSn)));
    query.addQueryItem("activationCode",QString(QUrl::toPercentEncoding(m_activationCode)));
    query.addQueryItem("lastRequestAt",QString(QUrl::toPercentEncoding(m_lastRequesetAt)));
    query.addQueryItem("cpu",QString(QUrl::toPercentEncoding(m_cpu)));
    query.addQueryItem("registerCode",QString(QUrl::toPercentEncoding(m_registerCode)));
    if (enableExperiencePlan)
        query.addQueryItem("enableExperiencePlan", QString(QUrl::toPercentEncoding("true")));
    else
        query.addQueryItem("enableExperiencePlan", QString(QUrl::toPercentEncoding("false")));
    url.setQuery(query.query());

    qDebug() << "ip:" << QString(QUrl::toPercentEncoding(m_ip))\
             << "mac:" << QString(QUrl::toPercentEncoding(m_mac))\
             << "eqptSn" << QString(QUrl::toPercentEncoding(m_eqptSn))\
             << "serverSn:" << QString(QUrl::toPercentEncoding(m_serverSn))\
             << "activationCode" << QString(QUrl::toPercentEncoding(m_activationCode)) << "lastRequestAt:" << QString(QUrl::toPercentEncoding(m_lastRequesetAt)) << "cpu" << QString(QUrl::toPercentEncoding(m_cpu))<< "register" << QString(QUrl::toPercentEncoding(m_registerCode));

    QNetworkRequest request;
    request.setUrl(url);
    if (urlStr.contains("https://")) {
        QSslConfiguration conf = request.sslConfiguration();
        conf.setPeerVerifyMode(QSslSocket::VerifyNone);
        conf.setProtocol(QSsl::TlsV1SslV3);
        request.setSslConfiguration(conf);
    }
    QNetworkAccessManager *manager = new QNetworkAccessManager();

    setNetworkProxy(manager, url.toString());
    qDebug() <<  manager->proxy().port() <<  manager->proxy().hostName();

    QTimer timer;
    QNetworkReply *reply = manager->get(request);
    QEventLoop eventLoop;
    connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
    connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
    timer.start(10000);
    eventLoop.exec();
    /*超时10s退出*/
    if(timer.isActive()) {
        timer.stop();
        ret = setUpdateTransaction(reply, var);
    } else {
        disconnect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
        reply->abort();
        reply->close();
        reply->deleteLater();
    }

    return ret;
}

/*
 * 设置更新事务
*/
bool MainSourceUpdate::setUpdateTransaction(QNetworkReply *reply, int var)
{
    qDebug() << "获取更新内容ID接口请求结束";
    bool ret = false;

    if (reply->error() == QNetworkReply::NoError) {
        QVariant statusCodeInfo = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        /*服务端返回200状态码为请求成功 其他都为请求失败*/
        if (statusCodeInfo.toInt() == 200) {
            QByteArray reason = reply->readAll();
            QString str = reason;
            QJsonParseError jsonerror;
            QJsonDocument document = QJsonDocument::fromJson(str.toUtf8(),&jsonerror);
            if (!document.isNull() && (jsonerror.error == QJsonParseError::NoError)) {
                if (document.isObject()) {
                    ret = true;
                    QJsonObject object = document.object();
                    int returnCode = object["code"].toInt();
                    if (returnCode != 0)
                        return true;
                    QJsonObject dataObj = object["data"].toObject();
                    qDebug() <<"data" << dataObj;
                    /*写入上次访问时间*/
                    QString currentRequsetAt = dataObj["currentRequestAt"].toString();
                    QSettings set("/var/lib/kylin-software-properties/data/request.info", QSettings::IniFormat);
                    set.setValue("Time/lasetRequsetTime", currentRequsetAt);
                    set.sync();
                    /*读取更新事务*/
                    QList<upgradeTransactionsInfo> upgradeTransactionList;
                    QJsonArray recordArr = dataObj["records"].toArray();
                    //没推送内容,还原源地址
                    if (recordArr.size() == 0){
                        restoreSource();
                        return true;
                    }
                    //遍历事务
                    for (int var = 0; var < recordArr.size(); ++var) {
                        QJsonObject recordObj = recordArr.at(var).toObject();
                        upgradeTransactionsInfo Traninfo;
                        Traninfo.order = recordObj["order"].toInt();
                        Traninfo.category = recordObj["category"].toObject()["code"].toInt();
                        qDebug() << "获取是否是体验计划" << recordObj["category"].toObject()["code"].toInt();
                        QList<upgradeNodeInfo> upgradeNodeInfoList;
                        QJsonArray nodeArr = recordArr.at(var).toObject()["nodes"].toArray();
                        //遍历事务中的节点
                        for (int var = 0; var < nodeArr.size(); ++var) {
                            QJsonObject nodeObj = nodeArr.at(var).toObject();
                            upgradeNodeInfo nodeInfo;
                            nodeInfo.uuid = nodeObj["uuid"].toString();
                            nodeInfo.order = nodeObj["order"].toInt();
                            nodeInfo.diffPkgConRel = nodeObj["diffPkgCondRel"].toObject()["code"].toString();
                            nodeInfo.isAdvancedMode = nodeObj["isAdvancedMode"].toBool();
                            nodeInfo.silentUpgrade = nodeObj["silentUpgrade"].toBool();
                            nodeInfo.category = nodeObj["category"].toObject()["code"].toInt();
                            nodeInfo.advConditionObj = nodeObj["advCondition"].toObject();
                            updateInfo upInfo;
                            upInfo.cruialPkgList = nodeObj["configInfo"].toObject()["crucialPackages"].toVariant().toStringList();
                            upInfo.importantPkgList = nodeObj["configInfo"].toObject()["importantPackages"].toVariant().toStringList();
                            QJsonArray sourceArr = nodeObj["configInfo"].toObject()["sources"].toArray();
                            QList <sourceInfo> sourceInfoList;
                            for (int var = 0; var < sourceArr.size(); ++var) {
                                QJsonObject sourceObj = sourceArr.at(var).toObject();
                                sourceInfo sourceinfo;
                                sourceinfo.link = sourceObj["link"].toString();
                                sourceinfo.priority = sourceObj["priority"].toObject()["code"].toInt();
                                if (sourceObj.contains("category")){
                                    sourceinfo.category = sourceObj["category"].toObject()["code"].toInt();
                                }else {
                                    sourceinfo.category = 2;
                                }
                                sourceInfoList.append(sourceinfo);
                            }
                            upInfo.sourceInfoList = sourceInfoList;
                            nodeInfo.upinfo = upInfo;
                            QList<updateConditions> conditList;
                            QJsonArray conditArr = nodeObj["conditions"].toArray();
                            for (int var = 0; var < conditArr.size(); ++var) {
                                QJsonObject conditObj = conditArr.at(var).toObject();
                                updateConditions conditInfo;
                                conditInfo.category = conditObj["category"].toObject()["code"].toInt();
                                if (!conditObj.contains("operator")){
                                    conditInfo.operatorCode = "=";
                                } else {
                                    QString tmp = conditObj["operator"].toObject()["code"].toString();
                                    if (m_operatorList.contains(tmp)){
                                        conditInfo.operatorCode = tmp;
                                    }else {
                                        conditInfo.operatorCode = "";
                                    }
                                }
                                conditInfo.value = conditObj["value"].toString();
                                conditInfo.pkgName = conditObj["name"].toString();
                                conditList.append(conditInfo);

                            }
                            nodeInfo.upCondit = conditList;
                            upgradeNodeInfoList.append(nodeInfo);
                        }
                        qSort(upgradeNodeInfoList.begin(), upgradeNodeInfoList.end(),[](const upgradeNodeInfo &infoA,const upgradeNodeInfo &infoB) {
                            return infoA.order < infoB.order;
                        });
                        Traninfo.nodesInfo = upgradeNodeInfoList;
                        upgradeTransactionList.append(Traninfo);
                    }
                    qSort(upgradeTransactionList.begin(), upgradeTransactionList.end(),[](const upgradeTransactionsInfo &infoA,const upgradeTransactionsInfo &infoB) {
                        return infoA.order < infoB.order;
                    });
                    setUpdateInfoByTransaction(upgradeTransactionList, true);
                }
            }
        }else {
            restoreSource();
            return false;
        }
    } else {
        restoreSource();
        return false;
    }
    return ret;
}

/*
 * 根据更新事务，设置更新内容，遍历整个事务的各个节点
*/

bool MainSourceUpdate::setUpdateInfoByTransaction(QList<upgradeTransactionsInfo> tranInfoList, bool isOnline)
{
    bool ret = false;
    bool isCondit = true;
    bool isHaveUpdate = false;
    bool isHaveCondit = false;
    int tranNum = 0;

    /*遍历事务*/
    for (tranNum = 0; tranNum < tranInfoList.size(); ++tranNum) {
        int allNodeNum = 0;
        int upgradesAllNodeNum = 0;
        int currentNodeNum = 0;
        upgradeTransactionsInfo tranInfo = tranInfoList.at(tranNum);
        int nodeNum = 0;

        /*遍历节点*/
        for (nodeNum = 0; nodeNum < tranInfo.nodesInfo.size(); ++nodeNum) {
            upgradeNodeInfo nodeInfo = tranInfo.nodesInfo.at(nodeNum);
            qDebug() << "遍历节点" << nodeInfo.uuid << nodeNum;

            /*判断条件是否是否高级模式*/
            if (nodeInfo.isAdvancedMode){
                if(parsingAdvConditions(nodeInfo.advConditionObj)){
                    isCondit = true;
                    isHaveCondit = true;
                }
            }else {
                /*判断更新条件*/
                isCondit = true;
                QStringList systemVersionList;
                QStringList patchVersionList;
                QStringList productLineList;
                QStringList archList;
                QString diffPkgCondRel = nodeInfo.diffPkgConRel;
                QStringList pkgNameList;
                QList<updateConditions> pkgList;
                QList<updateConditions> conditList = nodeInfo.upCondit;
                for (int var = 0; var < conditList.size(); ++var) {
                    isHaveCondit = true;
                    updateConditions upCondit = conditList.at(var);
                    switch (upCondit.category) {
                    case 1:
                        systemVersionList.append(upCondit.value);
                        break;
                    case 2:
                        patchVersionList.append(upCondit.value);
                        break;
                    case 3:
                        pkgList.append(upCondit);
                        pkgNameList.append(upCondit.pkgName);
                        break;
                    case 4:
                        productLineList.append(upCondit.value);
                        break;
                    case 5:
                        archList.append(upCondit.value);
                        break;
                    default:
                        break;
                    }
                }
                /*判断系统版本*/
                if (systemVersionList.size() != 0 && !systemVersionList.contains(m_systemVersion)){
                    isCondit = false;
                    continue;
                }
                /*判断补丁版本*/
                if (patchVersionList.size() != 0 && !patchVersionList.contains(m_patchVersion)){
                    isCondit = false;
                    continue;
                }
                /*判断产线版本*/
                if (productLineList.size() != 0 && !productLineList.contains(m_productLine)){
                    isCondit = false;
                    continue;
                }
                /*判断架构*/
                if (archList.size() != 0 && !archList.contains(m_arch)){
                    isCondit = false;
                    continue;
                }
                /*判断包版本*/
                if (pkgList.size() != 0){
                    bool pkgIsCondit = true;
                    QList<pkgDiffResult> pkgDiffResultList;
                    for (int var = 0; var < pkgList.size(); ++var) {
                        updateConditions pkgCondit = pkgList.at(var);
                        //不同包之前是或关系
                        if (diffPkgCondRel == "or"){
                            bool pkgIsCondit = false;
                            isCondit = false;
                            if (pkgCondit.operatorCode == "="){
                                int pkgEqCondit = 0;
                                foreach (pkgDiffResult pkgDiff, pkgDiffResultList) {
                                    if (pkgCondit.pkgName == pkgDiff.pkgName && pkgDiff.result && pkgDiff.operatorCode == "="){
                                        pkgEqCondit = 1;
                                        break;
                                    }
                                }
                                if (pkgEqCondit != 1){
                                    pkgEqCondit = 2;
                                    if(getPkgVersionFromPkgName(pkgCondit.pkgName) == pkgCondit.value){
                                        pkgEqCondit = 1;
                                    }
                                }
                                if (pkgEqCondit == 1){
                                    pkgDiffResult tmp;
                                    tmp.operatorCode = "=";
                                    tmp.pkgName = pkgCondit.pkgName;
                                    tmp.result = true;
                                    pkgDiffResultList.append(tmp);
                                    pkgIsCondit = true;
                                    isCondit = true;
                                    break;
                                }
                            }else if (pkgCondit.operatorCode == "!="){
                                int diffResult = 0;
                                foreach (pkgDiffResult pkgDiff, pkgDiffResultList) {
                                    if (pkgCondit.pkgName == pkgDiff.pkgName && m_operDiffList.contains(pkgDiff.operatorCode)){
                                        diffResult = 1;
                                        if (pkgDiff.result){
                                            diffResult = 2;
                                        }else {
                                            diffResult = 1;
                                        }
                                    }
                                }
                                pkgDiffResult tmp;
                                tmp.operatorCode = ">";
                                tmp.pkgName = pkgCondit.pkgName;
                                if(getPkgVersionFromPkgName(pkgCondit.pkgName) != pkgCondit.value){
                                    tmp.result = true;
                                    pkgDiffResultList.append(tmp);
                                    if (pkgNameList.count(pkgCondit.pkgName) == 1 || diffResult == 2){
                                        pkgIsCondit = true;
                                        isCondit = true;
                                        break;
                                    }
                                }else {
                                    tmp.result = false;
                                    pkgDiffResultList.append(tmp);
                                }
                            }else if (pkgCondit.operatorCode == ">="){
                                int diffResult = 0;
                                foreach (pkgDiffResult pkgDiff, pkgDiffResultList) {
                                    if (pkgCondit.pkgName == pkgDiff.pkgName && m_operDiffList.contains(pkgDiff.operatorCode)){
                                        diffResult = 1;
                                        if (pkgDiff.result){
                                            diffResult = 2;
                                        }else {
                                            diffResult = 1;
                                        }
                                    }
                                }
                                pkgDiffResult tmp;
                                tmp.operatorCode = ">";
                                tmp.pkgName = pkgCondit.pkgName;
                                if(diffPkgVersion(getPkgVersionFromPkgName(pkgCondit.pkgName), pkgCondit.value, ">=") == 0){
                                    tmp.result = true;
                                    pkgDiffResultList.append(tmp);
                                    if (pkgNameList.count(pkgCondit.pkgName) == 1 || diffResult == 2){
                                        pkgIsCondit = true;
                                        isCondit = true;
                                        break;
                                    }
                                }else {
                                    tmp.result = false;
                                    pkgDiffResultList.append(tmp);
                                }
                            }else if (pkgCondit.operatorCode == ">"){
                                int diffResult = 0;
                                foreach (pkgDiffResult pkgDiff, pkgDiffResultList) {
                                    if (pkgCondit.pkgName == pkgDiff.pkgName && m_operDiffList.contains(pkgDiff.operatorCode)){
                                        diffResult = 1;
                                        if (pkgDiff.result){
                                            diffResult = 2;
                                        }else {
                                            diffResult = 1;
                                        }
                                    }
                                }
                                pkgDiffResult tmp;
                                tmp.operatorCode = ">";
                                tmp.pkgName = pkgCondit.pkgName;
                                if(diffPkgVersion(getPkgVersionFromPkgName(pkgCondit.pkgName), pkgCondit.value, ">") == 0){
                                    tmp.result = true;
                                    pkgDiffResultList.append(tmp);
                                    if (pkgNameList.count(pkgCondit.pkgName) == 1 || diffResult == 2){
                                        pkgIsCondit = true;
                                        isCondit = true;
                                        break;
                                    }
                                }else {
                                    tmp.result = false;
                                    pkgDiffResultList.append(tmp);
                                }
                            }else if (pkgCondit.operatorCode == "<="){
                                int diffResult = 0;
                                foreach (pkgDiffResult pkgDiff, pkgDiffResultList) {
                                    if (pkgCondit.pkgName == pkgDiff.pkgName && m_operDiffList.contains(pkgDiff.operatorCode)){
                                        diffResult = 1;
                                        if (pkgDiff.result){
                                            diffResult = 2;
                                        }else {
                                            diffResult = 1;
                                        }
                                    }
                                }
                                pkgDiffResult tmp;
                                tmp.operatorCode = ">";
                                tmp.pkgName = pkgCondit.pkgName;
                                if(diffPkgVersion(getPkgVersionFromPkgName(pkgCondit.pkgName), pkgCondit.value, "<=") == 0){
                                    tmp.result = true;
                                    pkgDiffResultList.append(tmp);
                                    if (pkgNameList.count(pkgCondit.pkgName) == 1 || diffResult == 2){
                                        pkgIsCondit = true;
                                        isCondit = true;
                                        break;
                                    }
                                }else {
                                    tmp.result = false;
                                    pkgDiffResultList.append(tmp);
                                }
                            }else if (pkgCondit.operatorCode == "<"){
                                int diffResult = 0;
                                foreach (pkgDiffResult pkgDiff, pkgDiffResultList) {
                                    if (pkgCondit.pkgName == pkgDiff.pkgName && m_operDiffList.contains(pkgDiff.operatorCode)){
                                        diffResult = 1;
                                        if (pkgDiff.result){
                                            diffResult = 2;
                                        }else {
                                            diffResult = 1;
                                        }
                                    }
                                }
                                pkgDiffResult tmp;
                                tmp.operatorCode = ">";
                                tmp.pkgName = pkgCondit.pkgName;
                                if(diffPkgVersion(getPkgVersionFromPkgName(pkgCondit.pkgName), pkgCondit.value, "<") == 0){
                                    tmp.result = true;
                                    pkgDiffResultList.append(tmp);
                                    if (pkgNameList.count(pkgCondit.pkgName) == 1 || diffResult == 2){
                                        pkgIsCondit = true;
                                        isCondit = true;
                                        break;
                                    }
                                }else {
                                    tmp.result = false;
                                    pkgDiffResultList.append(tmp);
                                }
                            }
                        }else {
                            //不同包之间是与关系
                            QStringList pkgNameTrueList;
                            if (pkgCondit.operatorCode == "="){
                                foreach (updateConditions tmp, pkgList) {
                                    if(tmp.pkgName == pkgCondit.pkgName){
                                        if (getPkgVersionFromPkgName(pkgCondit.pkgName) == tmp.value){
                                            pkgNameTrueList << pkgCondit.pkgName;
                                        }
                                    }
                                }
                                if (!pkgNameTrueList.contains(pkgCondit.pkgName)){
                                    pkgIsCondit = false;
                                }
                            }else if (pkgCondit.operatorCode == "!="){
                                if(!(getPkgVersionFromPkgName(pkgCondit.pkgName) != pkgCondit.value)){
                                    pkgIsCondit = false;
                                }

                            }else if (pkgCondit.operatorCode == ">="){
                                if(!(diffPkgVersion(getPkgVersionFromPkgName(pkgCondit.pkgName), pkgCondit.value, ">=") == 0)){
                                    pkgIsCondit = false;
                                }
                            }else if (pkgCondit.operatorCode == "<="){
                                if(!(diffPkgVersion(getPkgVersionFromPkgName(pkgCondit.pkgName), pkgCondit.value, "<=") == 0)){
                                    pkgIsCondit = false;
                                }
                            }else if (pkgCondit.operatorCode == ">"){
                                if(!(diffPkgVersion(getPkgVersionFromPkgName(pkgCondit.pkgName), pkgCondit.value, ">") == 0)){
                                    pkgIsCondit = false;
                                }
                            }else if (pkgCondit.operatorCode == "<"){
                                if(!(diffPkgVersion(getPkgVersionFromPkgName(pkgCondit.pkgName), pkgCondit.value, "<") == 0)){
                                    pkgIsCondit = false;
                                }
                            }
                            /*单次循环中，只要有不符合条件的，直接退出循环，此次判断不符合条件*/
                            if(!pkgIsCondit){
                                isCondit = false;
                                break;
                            }
                        }
                    }
                    /*单次循环中，只要有不符合条件的，直接退出循环，此次判断不符合条件*/
                    if(!pkgIsCondit){
                        isCondit = false;
                        break;
                    }
                }
            }
            //符合推送条件，并且uuid没有更新过
            if (isCondit  && isHaveCondit) {
                int upgradeNodeNum = nodeNum;
                int tmp = nodeNum;
                if (nodeNum == tranInfo.nodesInfo.size() - 1){
                    upgradeNodeNum = nodeNum;
                }else {
                    tmp++;
                    for (tmp; tmp < tranInfo.nodesInfo.size(); ++tmp) {
                        if (tranInfo.nodesInfo.at(tmp).category == 2){
                            upgradeNodeNum = tmp;
                            break;
                        }
                    }
                }

                upgradeNodeInfo nodeUpgradeInfo = tranInfo.nodesInfo.at(upgradeNodeNum);
                qDebug() << "此次更新的uuid:" << nodeUpgradeInfo.uuid << upgradeNodeNum;
                if (uuidIsUpdate(nodeUpgradeInfo.uuid)){
                    qDebug() <<"已经更新过";
                    upgradesAllNodeNum++;
                    continue;
                }
                for (int var = nodeNum + 1; var < tranInfo.nodesInfo.size(); ++var) {
                    if (tranInfo.nodesInfo.at(var).category == 2){
                        allNodeNum++;
                    }
                }
                allNodeNum += upgradesAllNodeNum;
                currentNodeNum  = upgradesAllNodeNum + 1;

                if (currentNodeNum > allNodeNum){
                    allNodeNum = currentNodeNum;
                }

                m_uuid = nodeUpgradeInfo.uuid;
                //写入更新内容，以及uuid
                updateInfo upIn = nodeUpgradeInfo.upinfo;
                QStringList important = upIn.importantPkgList;
                QStringList cruial = upIn.cruialPkgList;
                QList<sourceInfo> sourceinfoList = nodeInfo.upinfo.sourceInfoList;
                QList<sourceInfo> upgradeinfoList = nodeUpgradeInfo.upinfo.sourceInfoList;
                QJsonArray sourceArr;
                QJsonArray upgradeSourceArr;
                for (int var = 0; var < sourceinfoList.size(); ++var) {
                    sourceInfo sourceinfo = sourceinfoList.at(var);
                    QJsonObject sourceObj;
                    sourceObj.insert("source", sourceinfo.link);
                    sourceObj.insert("priority", QString::number(sourceinfo.priority));
                    sourceObj.insert("category",sourceinfo.category);
                    sourceArr.append(sourceObj);
                }
                for (int var = 0; var < upgradeinfoList.size(); ++var) {
                    sourceInfo sourceinfo = upgradeinfoList.at(var);
                    QJsonObject sourceObj;
                    sourceObj.insert("source", sourceinfo.link);
                    sourceObj.insert("priority", QString::number(sourceinfo.priority));
                    sourceObj.insert("category",sourceinfo.category);
                    upgradeSourceArr.append(sourceObj);
                }
                /*写入系统源*/
                writeSourceTemplateFile(sourceArr,true);
                writeSourceTemplateFile(upgradeSourceArr,false);
                writeUpdatePkgList(cruial, important);

                qDebug() << "此次更新uuid :" << nodeUpgradeInfo.uuid <<"强制推送列表"<< cruial << "重要更新包" << important;
                /*写入本次更新的uuid，并且判断是否还有下个阶段的更新*/
                QSettings set("/var/lib/kylin-software-properties/config/updateID.conf", QSettings::IniFormat);
                if (set.value("update/uuid").toString() != nodeUpgradeInfo.uuid){
                    set.setValue("update/uuid", nodeUpgradeInfo.uuid);
                    m_uuidIsUpload = true;

                }
                /*如果是最后一个节点并且是最后一个事务 或者是第一个节点,则设置为false*/
                if ((nodeNum == tranInfo.nodesInfo.size() - 1) && (tranNum == tranInfoList.size() - 1) || nodeNum == 0){
                    set.setValue("update/haveNextNode", "false");
                }else {
                    set.setValue("update/haveNextNode", "true");
                }
                set.setValue("update/silentUpgrade", nodeUpgradeInfo.silentUpgrade);
                set.setValue("update/allNodeNum", allNodeNum);
                set.setValue("update/currentNodeNum", currentNodeNum);
                set.sync();
                if (isOnline)
                    postUpgradeStatus(nodeUpgradeInfo.uuid, 2, "");
                isHaveUpdate = true;
                break;
            }
        }
        if (isHaveUpdate){
            ret = true;
            break;
        }else {
            /*写入本次更新的uuid，并且判断是否还有下个阶段的更新*/
            QSettings set("/var/lib/kylin-software-properties/config/updateID.conf", QSettings::IniFormat);
            set.setValue("update/allNodeNum", "0");
            set.setValue("update/currentNodeNum", "0");
            set.sync();
            restoreSource();
        }
    }
    return ret;
}


/*
 * 判断UUID是否更新过
*/
bool MainSourceUpdate::uuidIsUpdate(QString uuid)
{
    bool ret =false;
    QFile confile("/var/lib/kylin-software-properties/data/upgrade.log");
    if (!confile.exists()){
        return false;
    }
    confile.open(QIODevice::ReadOnly);
    QByteArray tmp =  confile.readAll();
    if (QString(tmp).contains(uuid)){
        confile.close();
        return true;
    }else{
        confile.close();
        return false;
    }
    return ret;
}

/*
 * 从服务端获取主源信息
*/
bool MainSourceUpdate::getSourceInfoFromServer(int var)
{
    QString address = serverInfoList.at(var).address;
    QString port = QString::number(serverInfoList.at(var).port);
    QString tmpSn = m_eqptSn;
    tmpSn.replace("/","");
    tmpSn.replace("#","");
    QString url = address + ":" + port + "/client_v1/" + tmpSn + "/" + m_serverSn;
    qDebug() << "访问服务器的地址:"<< url;
    QNetworkRequest request;
    QNetworkAccessManager* naManager = new QNetworkAccessManager(this);
    request.setUrl(QUrl(url));
    if (url.contains("https://")) {
        QSslConfiguration conf = request.sslConfiguration();
        conf.setPeerVerifyMode(QSslSocket::VerifyNone);
        conf.setProtocol(QSsl::TlsV1SslV3);
        request.setSslConfiguration(conf);
    }

    setNetworkProxy(naManager, url);

    QNetworkReply *reply = naManager->get(request);
    QEventLoop eventLoop;
    connect(naManager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
    eventLoop.exec();
    bool ret = requestFinished(reply);
    if (ret) {
        return true;
    }else
        return false;
    return true;
}
bool MainSourceUpdate::requestFinished(QNetworkReply *reply)
{
    if (reply->error() == QNetworkReply::NoError) {
        QVariant statusCodeInfo = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
        /*服务端返回200状态码为请求成功 其他都为请求失败*/
        if (statusCodeInfo.toInt() == 200) {
            QByteArray reason = reply->readAll();
            QString str = reason;
            QJsonParseError jsonerror;
            QJsonDocument document = QJsonDocument::fromJson(str.toUtf8(),&jsonerror);
            if (!document.isNull() && (jsonerror.error == QJsonParseError::NoError)) {
                if (document.isObject()) {
                    QJsonObject object;
                    object = document.object();
                    QString importantlist = object["important"].toString();
                    QString cruciallist = object["crucial"].toString();
                    writeListFile(IMPORTANT_FILE_PATH,importantlist);
                    writeListFile(CRUCIAL_FILE_PATH,cruciallist);

                    /*写入模板文件*/
                    if (!object["have_serial"].toString().compare("false") || object["have_serial"].toString().isNull()) {
                        return true;
                    }
                    /*清理之前的模板文件*/
                    system("rm /var/lib/kylin-software-properties/template/kylin-source-template*");

                    /*清空ID文件*/
                    system("rm /var/lib/kylin-software-properties/config/updateID.conf");

                    QString updaterVersion = getPkgVersionFromPkgName("kylin-system-updater");

                    QString sourcelistPath = "";

                    if (updaterVersion >= "2.0.5.16-0k6.0"){
                        sourcelistPath = "/var/lib/kylin-system-updater/sources.list";
                    }else {
                        sourcelistPath = "/etc/apt/sources.list";
                    }

                    QString m_MainSource  = object["sources.list"].toString();
                    if (m_MainSource.compare("")) {
                        system("rm /etc/apt/preferences.d/archive*.pref");
                        QString tmp;
                        QJsonDocument document;
                        QJsonParseError err;
                        document = QJsonDocument::fromJson(m_MainSource.toUtf8(), &err);
                        if (err.error == QJsonParseError::NoError)
                        {
                            QJsonArray  data(document.array());
                            foreach (QJsonValue val, data) {
                                QJsonObject obj = val.toObject();
                                tmp.append(obj["source"].toString());
                                tmp.append("\n");
                                if (updaterVersion >= "2.0.5.16-0k6.0"){
                                    setSourcePriority(obj["source"].toString(), obj["priority"].toString(),false, 2);
                                }else {
                                    setSourcePriority(obj["source"].toString(), obj["priority"].toString(),true, 2);
                                }
                            }
                            m_MainSource = tmp;
                        } else
                            qDebug() << "Parse json " << m_MainSource.toUtf8() << " error: " << err.error;

                        QFile file(sourcelistPath);
                        if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
                            qDebug() << "/var/lib/kylin-software-properties/template/kylin-source-template-main.list打开失败！";
                        }
                        QTextStream stream(&file);
                        stream.setCodec("utf-8");
                        QString str = "# 本文件由源管理器管理，会定期检测与修复，请勿修改本文件\n";
                        stream << str;
                        stream << m_MainSource;
                        file.close();
                    }
                } else
                    return false;
            } else
                return false;
        } else {
            qDebug() <<"请求无效" << statusCodeInfo.toInt();
            return false;
        }
    } else {
        return false;
    }
    return true;
}
/*
 * 写入更新列表
*/
void MainSourceUpdate::writeListFile(QString fileName, QString debList)
{
    QFile file(fileName);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
        qDebug() << "file open failed!" << fileName;
    }
    QTextStream stream(&file);
    stream << debList;
    file.close();
}

/*
 * 写入主源模板文件
*/
void MainSourceUpdate::writeSourceTemplateFile(QJsonArray sourceArr, bool isSystemSource)
{
    if (isSystemSource){
        system("rm /etc/apt/preferences.d/archive*.pref");
        QString systemSource = "";
        foreach (QJsonValue val, sourceArr) {
            QJsonObject obj = val.toObject();
            systemSource.append(obj["source"].toString());
            systemSource.append("\n");
            setSourcePriority(obj["source"].toString(),obj["priority"].toString(), true, 2);
        }

        QDir dir("/etc/apt/");
        if (!dir.exists()){
            dir.mkdir("/etc/apt/");
        }
        QFile file("/etc/apt/sources.list");
        if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
            qDebug() << "/etc/apt/sources.list 打开失败！" << file.errorString();
        }
        QTextStream stream(&file);
        stream.setCodec("utf-8");
        QString str = "# 本文件由源管理器管理，会定期检测与修复，请勿修改本文件\n";
        stream << str;
        stream << systemSource;
        file.close();
    } else {
        system("rm /var/lib/kylin-system-updater/preferences.d/archive*.pref");
        system("rm /var/lib/kylin-software-properties/template/preferences.d/*");
        QString systemSource = "";
        QString tmpSource = "";
        foreach (QJsonValue val, sourceArr) {
            QJsonObject obj = val.toObject();
            if (obj["category"].toInt() == 1){
                systemSource.append(obj["source"].toString());
                systemSource.append("\n");
                setSourcePriority(obj["source"].toString(), obj["priority"].toString(), false, 2);
            } else {
                tmpSource.append(obj["source"].toString());
                tmpSource.append("\n");
                setSourcePriority(obj["source"].toString(), obj["priority"].toString(), false, 1);
            }
        }
        QDir dir("/var/lib/kylin-system-updater/");
        if (!dir.exists()){
            dir.mkdir("/var/lib/kylin-system-updater/");
        }
        QFile file("/var/lib/kylin-system-updater/sources.list");
        if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
            qDebug() << "/var/lib/kylin-system-updater/sources.list 打开失败！" << file.errorString();
        }
        QTextStream stream(&file);
        stream.setCodec("utf-8");
        QString str = "# 本文件由源管理器管理，会定期检测与修复，请勿修改本文件\n";
        stream << str;
        stream << systemSource;
        file.close();


        QDir dir1("/var/lib/kylin-software-properties/template/apt/");
        if (!dir1.exists()){
            dir1.mkdir("/var/lib/kylin-software-properties/template/apt/");
        }
        QFile file1("/var/lib/kylin-software-properties/template/apt/sources.list");
        if (!file1.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
            qDebug() << "/var/lib/kylin-software-properties/template/apt/sources.list 打开失败！";
        }
        QTextStream stream1(&file1);
        stream1.setCodec("utf-8");
        stream1 << tmpSource;
        file1.close();
    }
}

/*
 * 写入更新列表
*/
void MainSourceUpdate::writeUpdatePkgList(QStringList cruialList, QStringList importantList)
{
    qDebug() <<"============" << cruialList << importantList;
    QString cruial = "";
    QString important = "";

    foreach (QString str, cruialList) {
        cruial.append(str);
        cruial.append(" ");
    }
    foreach (QString str, importantList) {
        important.append(str);
        important.append(" ");
    }

    QFile file("/var/lib/kylin-software-properties/template/important.list");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
        qDebug() << "file open failed!";
    }
    QTextStream stream(&file);
    stream << important;
    file.close();

    QFile file1("/var/lib/kylin-software-properties/template/crucial.list");
    if (!file1.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
        qDebug() << "file open failed!";
    }
    QTextStream stream1(&file1);
    stream1 << cruial;
    file1.close();



}


/*
 * 设置源的优先级
*/
void MainSourceUpdate::setSourcePriority(QString source, QString priority, bool isSystemSource, int categorySource)
{
    qDebug() << "设置优先级函数";
    if (source.isNull() || priority.isNull() || priority == "0")
        return ;
    QString address;
    QStringList listTmp = source.split(" ");
    QString dist;
    for (int var = 0; var < listTmp.size(); ++var) {
        if (listTmp.at(var).contains("https://")) {
            address = listTmp.at(var);
            address.replace("https://", "");
            if (var < listTmp.size() - 1)
                dist = listTmp.at(var + 1);
        }
        else if (listTmp.at(var).contains("http://")){
            address = listTmp.at(var);
            address.replace("http://", "");
            if (var < listTmp.size() - 1)
                dist = listTmp.at(var + 1);
        }
        else if (listTmp.at(var).contains("ftp://")){
            address = listTmp.at(var);
            address.replace("ftp://", "");
            if (var < listTmp.size() - 1)
                dist = listTmp.at(var + 1);
        }
        QString tmp = address;
        if (tmp.contains("/")) {
            QStringList list = tmp.split("/");
            address = list.at(0);
        }
    }
    if (address.contains(":")) {
        QStringList list = address.split(":");
        address = list.at(0);
    }

    if (isSystemSource){
        QDir dir("/etc/apt/preferences.d");
        if (!dir.exists())
            dir.mkdir("/etc/apt/preferences.d");

        int num = 1;

        QString fileName;
        for(num = 1; num < 20;num++)
        {
            fileName = "/etc/apt/preferences.d/" +  QString("archive%1.pref").arg(num);
            QFile file2(fileName);
            if (!file2.exists())
                break;
        }

        QFile file(fileName);
        if (!file.open(QIODevice::Append | QIODevice::Truncate | QIODevice::Text)) {
            qDebug() << "/etc/apt/preferences.d/archive1.pref 打开失败！";
        }
        QTextStream stream(&file);
        stream.setCodec("utf-8");
        QString str = "# 本文件由源管理器管理，会定期检测与修复，请勿修改本文件\n";
        stream << str;
        stream << QString("Package: *\n");
        stream << QString("Pin: release a=%1\n").arg(dist);
        stream << QString("Pin-Priority: %1\n").arg(priority);
        file.close();
    }else {
        if (categorySource == 1){
            QDir dir("/var/lib/kylin-software-properties/template/preferences.d");
            if (!dir.exists())
                dir.mkdir("/var/lib/kylin-software-properties/template/preferences.d");

            int num = 1;

            QString fileName;
            for(num = 1; num < 20;num++)
            {
                fileName = "/var/lib/kylin-system-updater/preferences.d/" +  QString("archive%1.pref").arg(num);
                QString fileName2 = "/var/lib/kylin-software-properties/template/preferences.d/" +  QString("archive%1.pref").arg(num);
                QFile file2(fileName);
                QFile file3(fileName2);
                if (!file2.exists() && !file3.exists()){
                    break;
                }
            }
            fileName  = "/var/lib/kylin-software-properties/template/preferences.d/" +  QString("archive%1.pref").arg(num);
            QFile file(fileName);
            if (!file.open(QIODevice::Append | QIODevice::Truncate | QIODevice::Text)) {
                qDebug() << "/var/lib/kylin-software-properties/template/preferences.d/archive1.pref 打开失败！";
            }
            QTextStream stream(&file);
            stream.setCodec("utf-8");
            QString str = "# 本文件由源管理器管理，会定期检测与修复，请勿修改本文件\n";
            stream << str;
            stream << QString("Package: *\n");
            stream << QString("Pin: release a=%1\n").arg(dist);
            stream << QString("Pin-Priority: %1\n").arg(priority);
            file.close();
        }else {
            QDir dir("/var/lib/kylin-system-updater/preferences.d/");
            if (!dir.exists())
                dir.mkdir("/var/lib/kylin-system-updater/preferences.d/");

            int num = 1;

            QString fileName;
            for(num = 1; num < 20;num++)
            {
                fileName = "/var/lib/kylin-system-updater/preferences.d/" +  QString("archive%1.pref").arg(num);
                QFile file2(fileName);
                if (!file2.exists())
                    break;
            }
            QFile file(fileName);
            if (!file.open(QIODevice::Append | QIODevice::Truncate | QIODevice::Text)) {
                qDebug() << "/etc/apt/preferences.d/archive1.pref 打开失败！";
            }
            QTextStream stream(&file);
            stream.setCodec("utf-8");
            QString str = "# 本文件由源管理器管理，会定期检测与修复，请勿修改本文件\n";
            stream << str;
            stream << QString("Package: *\n");
            stream << QString("Pin: release a=%1\n").arg(dist);
            stream << QString("Pin-Priority: %1\n").arg(priority);
            file.close();
        }
    }
}

void MainSourceUpdate::sendUpdateTemplateSignal(QString status)
{
    QDBusMessage message =QDBusMessage::createSignal("/com/kylin/software/properties",
                                                     "com.kylin.software.properties.interface",
                                                     "updateTemplateStatus");
    message << status;
    bool ret = QDBusConnection::systemBus().send(message);
    qDebug() <<"发送更新软件源模版状态信号:" << status << "---->" << ret;
    message =QDBusMessage::createSignal("/com/kylin/software/properties",
                                        "com.kylin.software.properties.interface",
                                        "updateStageUpgradeStatus");
    message << status;
    ret = QDBusConnection::systemBus().send(message);
    UploadMessage(status);
}


QString MainSourceUpdate::getUploadMessage(QString status)
{

    QString important = "";
    QString cruial = "";
    QString sourceslist = "";

    QDateTime dateTime= QDateTime::currentDateTime();
    QString tempStr = dateTime.toString("yyyy-MM-dd hh:mm:ss.zzz");
    QProcess process;
    process.start("cat /var/lib/kylin-software-properties/template/important.list");
    process.waitForFinished(-1);
    QByteArray arr = process.readAll();
    important = QString(arr);
    process.close();
    if (important.contains("\n")) {
        important.remove("\n");
    }

    process.start("cat /var/lib/kylin-software-properties/template/crucial.list");
    process.waitForFinished(-1);
    arr = process.readAll();
    cruial = QString(arr);
    if (cruial.contains("\n")) {
        cruial.remove("\n");
    }

    process.start("cat /var/lib/kylin-system-updater/sources.list");
    process.waitForFinished(-1);
    arr = process.readAll();
    sourceslist = QString(arr);
    if (sourceslist.contains("\n")) {
        sourceslist.remove("\n");
    }

    QJsonObject jObject;
    QJsonDocument jDoc;
    jObject.insert("createTimeStamp", tempStr);
    jObject.insert("important", important);
    jObject.insert("crucial", cruial);
    jObject.insert("sourceslist", sourceslist);
    jObject.insert("status", status);
    jObject.insert("pushid", m_uuid);
    jDoc.setObject(jObject);

    //    qDebug() << QString(jDoc.toJson(QJsonDocument::Compact));
    return QString(jDoc.toJson(QJsonDocument::Compact));
}

int MainSourceUpdate::UploadMessage(QString status)
{

    /*如果此uuid已经上传过，那就不上传了*/
    if(!m_uuidIsUpload){
        return 0;
    }


    QString uploadedMessage = getUploadMessage(status);

    m_dbusInterface =  new QDBusInterface(s_serverName,s_objectPath,s_interfaceName,
                                          QDBusConnection::systemBus());

    UploadMessageReturnState uploadMessageReturnState;
    QString tid;
    QString nowTid;
    if (m_dbusInterface == nullptr)
    {
        return -1;
    }
    //  从配置文件中获取tid
    checkDir();
    QFile file1("/var/lib/kylin-software-properties/config/tid.conf");
    if (file1.exists()) {
        QSettings packageInfoIdSetting("/var/lib/kylin-software-properties/config/tid.conf",QSettings::Format::IniFormat);
        packageInfoIdSetting.beginGroup(s_uploadMessageConf);
        if(packageInfoIdSetting.contains(s_tid)) {
            tid = packageInfoIdSetting.value(s_tid).toString();
        }
        packageInfoIdSetting.endGroup();
    }

    // 生成packageInfo
    QJsonObject packageInfoJsonObj;
    packageInfoJsonObj.insert(s_packageName, m_packageName);
    packageInfoJsonObj.insert(s_messageType, m_messageType);
    packageInfoJsonObj.insert(s_tid, tid);
    QString packageInfo(QJsonDocument(packageInfoJsonObj).toJson(QJsonDocument::JsonFormat::Compact));
    // 计算sha256
    QCryptographicHash cryHash(QCryptographicHash::Algorithm::Sha256);
    cryHash.addData(uploadedMessage.toUtf8());
    QByteArray uploadedMessageSha256 = cryHash.result();
    //	加密数据
    QByteArray enUploadedMessageSha256 = encrypt(uploadedMessageSha256,publicKey).toBase64();
    //    //	调用函数
    //    qDebug()<<"packageInfo="<<packageInfo;
    //    qDebug()<<" tid="<<tid;
    //    qDebug()<<" uploadedMessage="<<uploadedMessage;
    //    //            <<" uploadedMessageSha256="<<uploadedMessageSha256
    //    qDebug()<<"	enUploadedMessageSha256="<<enUploadedMessageSha256;
    QDBusMessage dbusMessage = m_dbusInterface->call(QDBus::CallMode::Block, s_uploadMessageMethod,packageInfo,uploadedMessage,QString(enUploadedMessageSha256));
    //	获取返回值
    if (dbusMessage.type() == QDBusMessage::MessageType::ReplyMessage)
    {
        if(!dbusMessage.arguments().isEmpty())
        {
            QList<QVariant> retValue = dbusMessage.arguments();
            if(retValue.size()==2)
            {
                qDebug()<<"dBusRet="<<retValue;
                uploadMessageReturnState = static_cast<UploadMessageReturnState>(retValue.first().toInt());
                nowTid =  retValue.last().toString();
            }
            else
            {
                qDebug()<<"ret num error:"<<retValue.size();
                return -1;

            }
        }
        else
        {
            qDebug()<<"error Name:"<< dbusMessage.errorName() <<" errorMessage:"<<  dbusMessage.errorMessage();
            return -1;
        }
    }
    else
    {
        qDebug()<<"dbusMessage type ="<<dbusMessage.type()<<dbusMessage.errorMessage()<<dbusMessage.errorName();
        return -1;
    }
    //  检查返回值
    if (uploadMessageReturnState == UploadMessageReturnState::OK)
    {
        return 0;
    }
    else if(uploadMessageReturnState == UploadMessageReturnState::InvalidTid)
    {
        QSettings packageInfoIdSetting("/usr/share/kylin-szzf-cloectInfo/tid.conf",QSettings::Format::IniFormat);
        // 更新tid 更新tid  更新tid
        packageInfoIdSetting.beginGroup(s_uploadMessageConf);
        packageInfoIdSetting.setValue(s_tid,nowTid);
        packageInfoIdSetting.endGroup();
        return 0;
    }
    else
    {
        return -1;
    }
}

// 使用RSA公钥进行加密
QByteArray MainSourceUpdate::encrypt(const QByteArray &hasedValue, const QByteArray &keyBase64)
{
    BIO *bio = NULL;
    RSA *p_rsa = NULL;
    EVP_PKEY *key = NULL;
    EVP_PKEY_CTX *ctx = NULL;
    unsigned char *out;
    size_t outlen;
    QByteArray tempKey = QByteArray::fromBase64(keyBase64);
    if((bio = BIO_new_mem_buf(tempKey.data(),tempKey.size())) == NULL)
    {
        evpError();
        return QByteArray();
    }
    if((p_rsa=PEM_read_bio_RSA_PUBKEY(bio,NULL,NULL,NULL))==NULL)
    {
        evpError();
        BIO_free(bio);
        return QByteArray();
    }
    key = EVP_PKEY_new();
    if (key == NULL)
    {
        evpError();
        BIO_free(bio);
        RSA_free(p_rsa);
        return QByteArray();
    }
    if(EVP_PKEY_set1_RSA(key,p_rsa)<=0)
    {
        evpError();
        BIO_free(bio);
        RSA_free(p_rsa);
        EVP_PKEY_free(key);
        return QByteArray();
    }
    ctx = EVP_PKEY_CTX_new(key,NULL);
    if(ctx == NULL)
    {
        evpError();
        BIO_free(bio);
        RSA_free(p_rsa);
        EVP_PKEY_free(key);
        return QByteArray();
    }
    if(EVP_PKEY_encrypt_init(ctx) <=0)
    {
        evpError();
        BIO_free(bio);
        RSA_free(p_rsa);
        EVP_PKEY_free(key);
        EVP_PKEY_CTX_free(ctx);
        return QByteArray();
    }
    //  设置填充方式为OAEP
    if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0)
    {
        evpError();
        BIO_free(bio);
        RSA_free(p_rsa);
        EVP_PKEY_free(key);
        EVP_PKEY_CTX_free(ctx);
        return QByteArray();
    }

    //  确定加密buf长度
    if (EVP_PKEY_encrypt(ctx, NULL, &outlen, (const unsigned char *)hasedValue.data(), hasedValue.size()) <= 0)
    {
        evpError();
        BIO_free(bio);
        RSA_free(p_rsa);
        EVP_PKEY_free(key);
        EVP_PKEY_CTX_free(ctx);
        return QByteArray();
    }

    out = (unsigned char *) OPENSSL_malloc(outlen);

    if (!out)
    {
        evpError();
        BIO_free(bio);
        RSA_free(p_rsa);
        EVP_PKEY_free(key);
        EVP_PKEY_CTX_free(ctx);
        return QByteArray();
    }
    //  进行加密
    if (EVP_PKEY_encrypt(ctx, out, &outlen, (const unsigned char *)hasedValue.data(), hasedValue.size()) <= 0)
    {
        evpError();
        BIO_free(bio);
        RSA_free(p_rsa);
        EVP_PKEY_free(key);
        EVP_PKEY_CTX_free(ctx);
        OPENSSL_free(out);
        return QByteArray();
    }
    QByteArray retByteArray((const char *)out,outlen);
    OPENSSL_free(out);
    BIO_free(bio);
    RSA_free(p_rsa);
    EVP_PKEY_free(key);
    EVP_PKEY_CTX_free(ctx);
    return retByteArray;
}

//  打印错误信息
void MainSourceUpdate::evpError(void)
{
    int n  = ERR_get_error();
    char szErr[512];
    char errStr[1024];
    ERR_error_string( n, szErr );
    sprintf(errStr,"error code = %d,code string = %s",n,szErr);
    qWarning() << errStr;
}

void MainSourceUpdate::checkDir()
{
    QDir tempDir("/var/lib/kylin-software-properties/config/");
    if(!tempDir.exists())
    {
        tempDir.mkpath("/var/lib/kylin-software-properties/config/");
    }
}


/*
 * 获取系统版本以及补丁版本
*/
void MainSourceUpdate:: getSystemVersionAndPatchVersion()
{
    /*先获取buildID*/
    QString kybuilderID = "";
    QFile file("/etc/kylin-build");
    if(file.open(QIODevice::ReadOnly)){
        QByteArray arr = file.readAll();
        QString str = QString(arr);
        if (str.contains("buildid:")){
            QStringList  list =  str.split("buildid:");
            kybuilderID = list.at(1);
            kybuilderID.remove("\n").remove(" ");
        }
    }
    file.close();
    qDebug() << "kybuilderID:" << kybuilderID;
    if (kybuilderID == ""){
        QFile file("/etc/os-release");
        if(!file.open(QIODevice::ReadOnly)){
            qDebug() << "os-release 打开失败";
        }
        QString str = QString(file.readAll());
        if (str.contains("\n")){
            foreach (QString st, str.split("\n")) {
                if (st.contains("KYLIN_RELEASE_ID")){
                    m_systemVersion = st.remove("KYLIN_RELEASE_ID=");
                }
            }
        }
        file.close();

        m_systemVersion = m_systemVersion.replace("\"","");
        if (m_systemVersion == ""){
            qDebug() << "读取文件获取的版本号"  << m_systemVersion << m_patchVersion;
            if (m_systemVersion.isEmpty()){
                m_systemVersion = "2107";
            }
        }
    }else{
        QSettings set("/etc/kylin-version/kylin-system-version.conf", QSettings::IniFormat);
        QString system = set.value("SYSTEM/os_version").toString();
        QString patch = set.value("SYSTEM/update_version").toString();

        if (system != patch && patch != ""){
            m_systemVersion = patch;
        }else {
            m_systemVersion = kybuilderID;
        }
    }

    if (m_systemVersion.contains("*")){
        m_systemVersion.replace("*","");
    }

    return ;
}

void MainSourceUpdate::getCpuInfo()
{
    /*获取CPU信息*/
    QString cpuModel;
    QProcess process;
    process.start("cat /proc/cpuinfo");
    process.waitForFinished(-1);
    QByteArray arr = process.readAll();
    QStringList list =  QString(arr).split("\n");
    Q_FOREACH (QString str, list) {
        if (str.contains("Hardware")){
            cpuModel = str.split(":").at(1);
        }
    }
    if(QString(cpuModel).replace("\n","").replace(" ","").toLower() != "")
    {
        m_cpu = QString(cpuModel).replace("\n","").replace(" ","").toLower();
        if(sizeof(cpuModel) != 0)
        {
            if(m_cpu.contains("kirin990")  == true || (m_cpu.contains("kirin") == true && m_cpu.contains("990") == true))
            {
                m_cpu = "kirin990";
            }
            else if(m_cpu.contains("huaweikirin9006C")  == true || (m_cpu.contains("kirin") == true && m_cpu.contains("9006c") == true))
            {
                m_cpu = "kirin9006c";
            }
        }
        else
        {
            process.start("cat /proc/cpuinfo");
            process.waitForFinished(-1);
            QByteArray arr = process.readAll();
            QStringList list =  QString(arr).split("\n");
            Q_FOREACH (QString str, list) {
                if (str.contains("model name")){
                    cpuModel = str.split(":").at(1);
                }
            }
            if(QString(cpuModel).replace("\n","").replace(" ","").toLower() != "")
            {
                m_cpu = QString(cpuModel).replace("\n","").replace(" ","");
                if(m_cpu.contains("Intel"))
                {
                    m_cpu = "Intel";
                }
                else if(m_cpu.contains("AMD"))
                {
                    m_cpu = "AMD";
                }
                else if(m_cpu.contains("Hygon"))
                {
                    m_cpu = "HYGON";
                }
                else if(m_cpu.contains("ZHAOXIN"))
                {
                    m_cpu = "ZHAOXIN";
                }
                else if((m_cpu.contains("FT2000A") && m_cpu.contains("4-Core")) || m_cpu.contains("FT-2000"))
                {
                    m_cpu = "FT2000/4";
                }

                else if (m_cpu.toLower().contains("loongson") &&  m_cpu.toLower().contains("3a4000")){
                    m_cpu = "loongson3A R4(Loongson3A4000)";
                }
                else
                {
                    if(m_cpu.contains("D2000") && m_cpu.contains("Phytium"))
                    {
                        m_cpu = "D2000";
                    }
                    else
                    {
                        if(m_cpu.split(",").length() > 1)
                        {
                            m_cpu = m_cpu.split(",")[1].replace(" ","").replace("\n","");
                        }
                    }
                }
            }
        }
    }
    else
    {
        process.start("cat /proc/cpuinfo");
        process.waitForFinished(-1);
        QByteArray arr = process.readAll();
        QStringList list =  QString(arr).split("\n");
        Q_FOREACH (QString str, list) {
            if (str.contains("model name")){
                cpuModel = str.split(":").at(1);
            }
        }
        if(QString(cpuModel).replace("\n","").replace(" ","").toLower() != "")
        {
            m_cpu = QString(cpuModel).replace("\n","").replace(" ","");
            if(m_cpu.contains("Intel"))
            {
                m_cpu = "Intel";
            }
            else if(m_cpu.contains("AMD"))
            {
                m_cpu = "AMD";
            }
            else if(m_cpu.contains("Hygon"))
            {
                m_cpu = "HYGON";
            }
            else if(m_cpu.contains("ZHAOXIN"))
            {
                m_cpu = "ZHAOXIN";
            }
            else if((m_cpu.contains("FT2000A") && m_cpu.contains("4-Core")) || m_cpu.contains("FT-2000"))
            {
                m_cpu = "FT2000/4";
            }
            else if (m_cpu.toLower().contains("loongson") &&  m_cpu.toLower().contains("3a4000")){
                m_cpu = "loongson3A R4(Loongson3A4000)";
            }
            else
            {
                if(m_cpu.contains("D2000") && m_cpu.contains("Phytium"))
                {
                    m_cpu = "D2000";
                }
                else
                {
                    if(m_cpu.split(",").length() > 1)
                    {
                        m_cpu = m_cpu.split(",")[1].replace(" ","").replace("\n","");
                    }
                }
            }
        }
    }
    if(m_cpu.toLower().contains("kunpeng") && m_cpu.toLower().contains("920"))
        m_cpu = "Kunpeng920";
    process.close();
    return;
}


void MainSourceUpdate::getLastRequestAtTime()
{
    QSettings set("/var/lib/kylin-software-properties/data/request.info", QSettings::IniFormat);

    m_lastRequesetAt = set.value("Time/lasetRequsetTime").toString();
}


QString MainSourceUpdate::getPkgVersionFromPkgName(QString pkgname)
{

    if (pkgname == "" || pkgname.contains("`") || pkgname.contains("&")){
        return "0";
    }
    QString pkgVersion = "";
    QString lastLine ="";
    QString cmd  = "dpkg -l " + pkgname;
    QProcess process;
    process.start(cmd);
    process.waitForFinished();
    QString output = process.readAllStandardOutput();
    QStringList list = output.split("\n");
    if (list.size() > 2){
        lastLine  = list.at(list.size()-2);
        lastLine.replace(QRegExp("[\\s]+"), " ");
    }

    if (lastLine.contains(pkgname) && lastLine.contains(" ")){
        QStringList tmpList = lastLine.split(" ");
        if (tmpList.size() > 3) {
            pkgVersion = tmpList.at(2);
        }
    }
    process.close();
    if (pkgVersion == ""){
        return "0.0000";
    }
    return pkgVersion;
}
//获取当前系统环境是什么产线
void MainSourceUpdate::getProductLine()
{
    //通过dpkg -l 获取ukui-control-center的版本
    QString UKCVersion = getPkgVersionFromPkgName("ukui-control-center");

    //获取内核版本
    QProcess process;
    process.start("uname -r");
    process.waitForFinished(-1);
    QByteArray arr = process.readAll();
    process.close();
    QString kernelVersion = QString(arr).remove("\n");

    if (kernelVersion.size() < 6){
        kernelVersion.append("0.0.0.0");
    }

    //获取架构
    process.start("arch");
    process.waitForFinished(-1);
    arr = process.readAll();
    QString arch = QString(arr).remove("\n");
    m_arch = arch;


    if (arch == "sw_64" || arch == "loongarch64" || arch == "mips64"){
        if (UKCVersion.left(4) == "3.24"){
            m_productLine = "xc-2303u2";
        }else {
            m_productLine = "xc";
        }
        return ;
    }
    //获取cpu
    QFile file("/proc/cpuinfo");
    QString tmp;
    if (file.open(QIODevice::ReadOnly)){
        QByteArray arr = file.readAll();
        tmp = QString(arr);
    }
    file.close();
    QStringList list = tmp.split("\n");
    foreach (QString str, list) {
        if (str.toLower().contains("model name")){
            //arm架构，内核版本为5.4.18或者cpu为飞腾鲲鹏
            if (arch.toLower() == "aarch64" && (str.toLower().contains("phytium") || str.toLower().contains("kunpeng") \
                                                || str.toLower().contains("ft-2000") || str.toLower().contains("d2000") \
                                                || str.toLower().contains("ft2000") || kernelVersion.left(6) == "5.4.18")){
                if (UKCVersion.left(4) == "3.24"){
                    m_productLine = "xc-2303u2";
                }else {
                    m_productLine = "xc";
                }
                return;
                //x86架构，内核版本为5.4.18 或者cpu为zhaoxin 海光
            }else if (arch.toLower() == "x86_64" && (str.toLower().contains("zhaoxin") || str.toLower().contains("hygon")
                                                     || kernelVersion.left(6) == "5.4.18")){
                if (UKCVersion.left(4) == "3.24"){
                    m_productLine = "xc-2303u2";
                }else {
                    m_productLine = "xc";
                }
                return;
            }else if (arch.toLower() == "x86_64" && (str.toLower().contains("intel") || str.toLower().contains("amd"))){
                if (kernelVersion.left(3) == "5.4"){
                    if (UKCVersion.left(4) == "3.24"){
                        m_productLine = "xc-2303u2";
                    }else {
                        m_productLine = "xc";
                    }
                    return;
                }else if (kernelVersion.left(4) == "5.10"){
                    if (UKCVersion.left(4) == "3.24"){
                        m_productLine = "hwe-2303u2";
                    }else {
                        m_productLine = "hwe";
                    }
                    return;
                }else if (kernelVersion.left(4) == "5.15"){
                    if (UKCVersion.left(4) == "3.24"){
                        m_productLine = "hwe-pp-2303u2";
                    }else {
                        m_productLine = "hwe-pp";
                    }
                    return;
                }
            }
        }
        if (str.toLower().contains("hardware")){
            if (arch.toLower() == "aarch64" && (((str.toLower().contains("kirin") && str.toLower().contains("990")) || kernelVersion.left(6) == "4.19.71"))){
                if (UKCVersion.left(4) == "3.24"){
                    m_productLine = "wayland-990-2303u2";
                }else {
                    m_productLine = "wayland-990";
                }
                return ;
            }else if (arch.toLower() == "aarch64" && (((str.toLower().contains("kirin") && str.toLower().contains("9006c")) || kernelVersion.left(6) == "5.4.96"))){
                if (UKCVersion.left(4) == "3.24"){
                    m_productLine = "wayland-9006c-2303u2";
                }else {
                    m_productLine = "wayland-9006c";
                }
                return ;
            }
        }
    }
}

/*
 * 离线读取事务
*/
void MainSourceUpdate::readUpdateTransaction(QJsonObject obj, QString filePath)
{
    /*读取更新事务*/
    QList<upgradeTransactionsInfo> upgradeTransactionList;
    QJsonArray recordArr = obj["records"].toArray();
    //遍历事务
    for (int var = 0; var < recordArr.size(); ++var) {
        QJsonObject recordObj = recordArr.at(var).toObject();
        upgradeTransactionsInfo Traninfo;
        Traninfo.order = recordObj["order"].toInt();
        Traninfo.category = recordObj["category"].toObject()["code"].toInt();
        qDebug() << "获取是否是体验计划" << recordObj["category"].toObject()["code"].toInt();
        QList<upgradeNodeInfo> upgradeNodeInfoList;
        QJsonArray nodeArr = recordArr.at(var).toObject()["nodes"].toArray();
        //遍历事务中的节点
        for (int var = 0; var < nodeArr.size(); ++var) {
            QJsonObject nodeObj = nodeArr.at(var).toObject();
            upgradeNodeInfo nodeInfo;
            nodeInfo.uuid = nodeObj["uuid"].toString();
            nodeInfo.order = nodeObj["order"].toInt();
            nodeInfo.diffPkgConRel = nodeObj["diffPkgCondRel"].toObject()["code"].toString();
            nodeInfo.isAdvancedMode = nodeObj["isAdvancedMode"].toBool();
            nodeInfo.silentUpgrade = nodeObj["silentUpgrade"].toBool();
            nodeInfo.category = nodeObj["category"].toObject()["code"].toInt();
            nodeInfo.advConditionObj = nodeObj["advCondition"].toObject();
            updateInfo upInfo;
            qDebug() << nodeObj["configInfo"].toObject();
            upInfo.cruialPkgList = nodeObj["configInfo"].toObject()["crucialPackages"].toVariant().toStringList();
            upInfo.importantPkgList = nodeObj["configInfo"].toObject()["importantPackages"].toVariant().toStringList();
            QJsonArray sourceArr = nodeObj["configInfo"].toObject()["sources"].toArray();
            QList <sourceInfo> sourceInfoList;
            for (int var = 0; var < sourceArr.size(); ++var) {
                QJsonObject sourceObj = sourceArr.at(var).toObject();
                sourceInfo sourceinfo;
                sourceinfo.link = getLinkByFilePath(sourceObj["link"].toString(), filePath);
                sourceinfo.priority = sourceObj["priority"].toObject()["code"].toInt();
                if (sourceObj.contains("category")){
                    sourceinfo.category = sourceObj["category"].toObject()["code"].toInt();
                }else {
                    sourceinfo.category = 2;
                }
                sourceInfoList.append(sourceinfo);
            }
            upInfo.sourceInfoList = sourceInfoList;
            nodeInfo.upinfo = upInfo;
            QList<updateConditions> conditList;
            QJsonArray conditArr = nodeObj["conditions"].toArray();
            for (int var = 0; var < conditArr.size(); ++var) {
                QJsonObject conditObj = conditArr.at(var).toObject();
                updateConditions conditInfo;
                conditInfo.category = conditObj["category"].toObject()["code"].toInt();
                if (!conditObj.contains("operator")){
                    conditInfo.operatorCode = "=";
                } else {
                    QString tmp = conditObj["operator"].toObject()["code"].toString();
                    if (m_operatorList.contains(tmp)){
                        conditInfo.operatorCode = tmp;
                    }else {
                        conditInfo.operatorCode = "";
                    }
                }
                conditInfo.value = conditObj["value"].toString();
                conditInfo.pkgName = conditObj["name"].toString();
                conditList.append(conditInfo);

            }
            nodeInfo.upCondit = conditList;
            upgradeNodeInfoList.append(nodeInfo);
        }
        qSort(upgradeNodeInfoList.begin(), upgradeNodeInfoList.end(),[](const upgradeNodeInfo &infoA,const upgradeNodeInfo &infoB) {
            return infoA.order < infoB.order;
        });
        Traninfo.nodesInfo = upgradeNodeInfoList;
        upgradeTransactionList.append(Traninfo);
    }
    qSort(upgradeTransactionList.begin(), upgradeTransactionList.end(),[](const upgradeTransactionsInfo &infoA,const upgradeTransactionsInfo &infoB) {
        return infoA.order < infoB.order;
    });

    setUpdateInfoByTransaction(upgradeTransactionList, false);

}

QString MainSourceUpdate::getLinkByFilePath(QString link, QString filePath)
{
    QString src;
    QDir distDir(filePath + link);
    if (distDir.exists()){
        distDir.setFilter(QDir::Dirs  | QDir::NoDotAndDotDot);
        QFileInfoList distList = distDir.entryInfoList();
        src = "deb file://" + filePath.remove("dists/") + " " + link;
        foreach (QFileInfo branchStr, distList) {
            src.append(" ");
            src.append(branchStr.fileName());
        }
    }
    return src;
}

int MainSourceUpdate::diffPkgVersion(QString srcVersion, QString destVersion, QString operatorCode)
{

    QString cmd;
    if (srcVersion == ""){
        srcVersion = "0";
    }

    if (operatorCode == ">"){
        cmd = "dpkg --compare-versions " + srcVersion + " gt " + destVersion;
    }else if (operatorCode == ">="){
        cmd = "dpkg --compare-versions " + srcVersion + " ge " + destVersion;
    }else if (operatorCode == "<"){
        cmd = "dpkg --compare-versions " + srcVersion + " lt " + destVersion;
    }else if (operatorCode == "<="){
        cmd = "dpkg --compare-versions " + srcVersion + " le " + destVersion;
    }
    QProcess process;
    process.start(cmd);
    process.waitForFinished(-1);
    if (process.exitCode() == 0){
        process.close();
        return 0;
    }else {
        process.close();
        return 1;
    }

}
//备份源
void MainSourceUpdate::backUpSource()
{
    QFile file("/usr/share/kylin-software-properties/backup/");
    if (file.exists()){
        return ;
    }
    QDir dir("/usr/share/kylin-software-properties/backup");
    if (!dir.exists()){
        dir.mkpath("/usr/share/kylin-software-properties/backup");
    }

    system("cp /etc/apt/sources.list /usr/share/kylin-software-properties/backup/sources.list.bk");

}
//还原源
void MainSourceUpdate::restoreSource()
{
    /*如果sources.list是file:///类型的，说明之前是离线源，还原成修改离线源之前的地址*/
    QFile file("/etc/apt/sources.list");
    if (!file.open(QIODevice::ReadOnly)){
        qDebug() << "/etc/apt/sources.list 不存在";
    }
    QByteArray arr =  file.readAll();
    QString tmp = QString(arr);
    file.close();
    if (tmp.contains("file:///") || !tmp.compare("")){
        //之前是光盘源
        QFile file("/usr/share/kylin-software-properties/backup/");
        if (file.exists()){
            system("mv /usr/share/kylin-software-properties/backup/sources.list.bk /etc/apt/sources.list");
        }
    }

    writeUpdatePkgList(QStringList(""), QStringList(""));
    QSettings set("/var/lib/kylin-software-properties/config/updateID.conf", QSettings::IniFormat);
    set.setValue("update/uuid", "gfdsgf");
}

void MainSourceUpdate::setNetworkProxy(QNetworkAccessManager *manager, QString url)
{
    //代理问题
    /*判断代理是否开启*/
    QProcess p;
    p.start("who");
    p.waitForReadyRead(-1);
    p.waitForFinished(-1);
    QByteArray arr = p.readAll();
    p.close();
    QString tmp = QString(arr.replace("\n",""));
    QString who = "";
    if (tmp.contains(" ")){
        who  = tmp.split(" ").at(0);
    }
    QNetworkProxy proxy;
    if (url.contains("http://")) {

        QProcess process2;
        process2.start("sudo -u "+ who +" dbus-launch --exit-with-session gsettings get org.gnome.system.proxy mode");
        process2.waitForReadyRead(-1);
        arr = process2.readAll();
        process2.waitForFinished(-1);
        process2.close();
        QString enable = QString(arr.replace("\n","").replace("'",""));
        if (!enable.compare("manual")){
            QProcess process;
            process.start("sudo -u "+ who +" dbus-launch --exit-with-session gsettings get org.gnome.system.proxy.http port");
            process.waitForReadyRead(-1);
            arr = process.readAll();
            QString port = QString(arr.replace("\n",""));
            process.waitForFinished(-1);
            process.close();
            qDebug() << "proxy port:" << port;

            QProcess process1;
            process1.start("sudo -u "+ who +" dbus-launch --exit-with-session gsettings get org.gnome.system.proxy.http host");
            process1.waitForReadyRead(-1);
            arr = process1.readAll();
            process1.close();
            QString host = QString(arr.replace("\n","").replace("'",""));

            proxy.setType(QNetworkProxy::HttpProxy);
            proxy.setHostName(host);
            proxy.setPort(port.toInt());
        }
    }
    if (url.contains("https://")) {
        QProcess process2;
        process2.start("sudo -u "+ who +" dbus-launch --exit-with-session gsettings get org.gnome.system.proxy mode");
        process2.waitForReadyRead(-1);
        arr = process2.readAll();
        process2.waitForFinished(-1);
        process2.close();
        QString enable = QString(arr.replace("\n","").replace("'",""));
        if (!enable.compare("manual")){
            QProcess process;
            process.start("sudo -u "+ who +" dbus-launch --exit-with-session gsettings get org.gnome.system.proxy.https port");
            process.waitForReadyRead(-1);
            arr = process.readAll();
            QString port = QString(arr.replace("\n",""));
            process.waitForFinished(-1);
            process.close();

            QProcess process1;
            process1.start("sudo -u "+ who +" dbus-launch --exit-with-session gsettings get org.gnome.system.proxy.https host");
            process1.waitForReadyRead(-1);
            arr = process1.readAll();
            process1.close();
            QString host = QString(arr.replace("\n","").replace("'",""));

            proxy.setType(QNetworkProxy::HttpProxy);
            proxy.setHostName(host);
            proxy.setPort(port.toInt());
        }
    }
    manager->setProxy(proxy);
}
void MainSourceUpdate::postUpgradeStatus(QString uuid, int statusCode, QString description)
{
    readyForUpdate();
    if (uuid == lastUUid && statusCode == lastStatusCode && uuid != "jm0qhvdz3g"){
        /*已经上报过*/
        return ;
    }
    if (statusCode == 2){
        QFile file2("/var/lib/kylin-software-properties/data/updateHistory.log");
        if (file2.exists()){
            if (!file2.open(QIODevice::ReadOnly)){
                qDebug() <<"/var/lib/kylin-software-properties/data/updateHistory.log" << file2.errorString();
            }
            QByteArray arr = file2.readAll();
            QString strtmp = QString(arr);
            file2.close();
            if (strtmp.contains(uuid) && uuid != "jm0qhvdz3g"){
                qDebug() << "已经上传过";
                return ;
            }
        }
    }
    QDateTime dateTime= QDateTime::currentDateTime();
    QString tempStr = dateTime.toString("yyyy-MM-dd hh:mm:ss");

    QJsonDocument jsonDoc;
    QJsonObject obj;
    obj.insert("nodeUuid", uuid);
    obj.insert("statusCode", statusCode);
    obj.insert("executedAt", tempStr);
    obj.insert("mac", m_mac);
    obj.insert("eqptSn", m_eqptSn);
    obj.insert("serverSn", m_serverSn);
    obj.insert("ip", m_ip);
    obj.insert("cpu", m_cpu);
    obj.insert("activationCode", m_activationCode);
    obj.insert("registerCode", m_registerCode);
    obj.insert("description", description);

    jsonDoc.setObject(obj);

    //获取服务器地址
    QString address = serverHost;
    QString port = QString::number(serverPort);

    if (address == ""){
        address = "http://archive1.kylinos.cn";
        port = "59546";
    }
    //构建URL
    QString urlStr = "";
    if (!port.compare("")){
        urlStr = address + "/node/report";
    } else {
        urlStr = address + ":" + port + "/node/report";
    }
    qDebug() << "上传地址："<< urlStr;

    QNetworkRequest request;
    request.setUrl(QUrl(urlStr));
    if (urlStr.contains("https://")) {
        QSslConfiguration conf = request.sslConfiguration();
        conf.setPeerVerifyMode(QSslSocket::VerifyNone);
        conf.setProtocol(QSsl::TlsV1SslV3);
        request.setSslConfiguration(conf);
    }
    QNetworkAccessManager *manager = new QNetworkAccessManager();

    setNetworkProxy(manager, urlStr);
    request.setRawHeader("Content-Type", "application/json; charset=utf-8");

    QTimer timer;
    QNetworkReply *reply = manager->post(request, jsonDoc.toJson(QJsonDocument::Compact));
    QEventLoop eventLoop;
    connect(&timer, &QTimer::timeout, &eventLoop, &QEventLoop::quit);
    connect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
    timer.start(5000);
    eventLoop.exec();
    /*超时10s退出*/
    if(timer.isActive()) {
        timer.stop();
        if (reply->error() == QNetworkReply::NoError) {
            QVariant statusCodeInfo = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
            /*服务端返回200状态码为请求成功 其他都为请求失败*/
            if (statusCodeInfo.toInt() == 200) {
                QByteArray reason = reply->readAll();
                QString str = reason;
                qDebug() << "========" << QString(str);
                QJsonParseError jsonerror;
                QJsonDocument document = QJsonDocument::fromJson(str.toUtf8(),&jsonerror);
                if (!document.isNull() && (jsonerror.error == QJsonParseError::NoError)) {
                    if (document.isObject()) {
                        QJsonObject object = document.object();
                        int returnCode = object["code"].toInt();
                        if (returnCode != 0){
                            //上传失败，保存数据，下次上传
                            goto saveInfo;
                        }else {
                            if(statusCode != 2 && uuid != "jm0qhvdz3g"){
                                QFile file2("/var/lib/kylin-software-properties/data/updateHistory.log");
                                if (!file2.open(QIODevice::WriteOnly | QIODevice::Append)){
                                    qDebug() <<"/var/lib/kylin-software-properties/data/updateHistory.log" << file2.errorString();
                                }
                                file2.write(uuid.toUtf8());
                                file2.write("\n");
                                file2.close();
                            }
                            if (statusCode == 7){
                                /*静默更新完成等于这个节点完成*/
                                QFile file2("/var/lib/kylin-software-properties/data/upgrade.log");
                                if (!file2.open(QIODevice::WriteOnly | QIODevice::Append)){
                                    qDebug() <<"/var/lib/kylin-software-properties/data/upgrade.log" << file2.errorString();
                                }
                                file2.write(uuid.toUtf8());
                                file2.write("\n");
                                file2.close();
                            }

                            lastUUid = uuid;
                            lastStatusCode = statusCode;
                            return ;
                        }
                    }
                }
            }else {
                //上传失败，保存数据，下次上传
                goto saveInfo;
            }
        }
    } else {
        //上传失败，保存数据
        goto saveInfo;
        disconnect(manager, &QNetworkAccessManager::finished, &eventLoop, &QEventLoop::quit);
        reply->abort();
        reply->close();
        reply->deleteLater();
    }

saveInfo:
    QFile file("/var/lib/kylin-software-properties/data/upload.log");
    if (!file.open(QIODevice::WriteOnly | QIODevice::Append)){
        qDebug() <<"/var/lib/kylin-software-properties/data/upload.log 打开失败" << file.errorString();
    }
    QString str = jsonDoc.toJson(QJsonDocument::Compact).simplified();
    file.write(str.toUtf8());
    file.write("\n");

    file.close();
    return ;

}

/*
 * 解析高级模式条件
*/
bool MainSourceUpdate::parsingAdvConditions(QJsonObject advConditObj)
{

    LogicNode * rootNode = new LogicNode(advConditObj["childrenLogic"].toObject()["code"].toString());
    getChildren(advConditObj["children"].toArray(), rootNode);

    return rootNode->evaluate();
}
/*
 * 获取子节点的条件
*/
void MainSourceUpdate::getChildren(QJsonArray childrenArray, LogicNode *rootNode)
{
    foreach (QJsonValue objtmp, childrenArray) {
        if (!objtmp.isNull()){
            QJsonObject obj = objtmp.toObject();
            qDebug() <<"obj" << obj;
            if (obj.keys().contains("condition")){
                int categoryCode = obj["condition"].toObject()["category"].toObject()["code"].toInt();
                LogicNode * node;
                switch (categoryCode) {
                case 1:
                    if (m_systemVersion == obj["condition"].toObject()["value"].toString()){
                        node = new LogicNode("true");
                    }else {
                        node = new LogicNode("false");
                    }
                    break;
                case 3:
                    if (obj["condition"].toObject()["operator"].toObject()["code"].toString() == "="){
                        if(getPkgVersionFromPkgName(obj["condition"].toObject()["name"].toString()) == obj["condition"].toObject()["value"].toString()){
                            node = new LogicNode("true");
                        }else{
                            node = new LogicNode("false");
                        }
                    }else if(obj["condition"].toObject()["operator"].toObject()["code"].toString() == "!="){
                        if(getPkgVersionFromPkgName(obj["condition"].toObject()["name"].toString()) != obj["condition"].toObject()["value"].toString()){
                            node = new LogicNode("true");
                        }else{
                            node = new LogicNode("false");
                        }

                    }else if(obj["condition"].toObject()["operator"].toObject()["code"].toString() == ">="){
                        if(diffPkgVersion(getPkgVersionFromPkgName(obj["condition"].toObject()["name"].toString()), obj["condition"].toObject()["value"].toString(), ">=") == 0){
                            node = new LogicNode("true");
                        }else{
                            node = new LogicNode("false");
                        }
                    }else if(obj["condition"].toObject()["operator"].toObject()["code"].toString() == ">"){
                        if(diffPkgVersion(getPkgVersionFromPkgName(obj["condition"].toObject()["name"].toString()), obj["condition"].toObject()["value"].toString(), ">") == 0){
                            node = new LogicNode("true");
                        }else{
                            node = new LogicNode("false");
                        }

                    }else if(obj["condition"].toObject()["operator"].toObject()["code"].toString() == "<="){
                        if(diffPkgVersion(getPkgVersionFromPkgName(obj["condition"].toObject()["name"].toString()), obj["condition"].toObject()["value"].toString(), "<=") == 0){
                            node = new LogicNode("true");
                        }else{
                            node = new LogicNode("false");
                        }

                    }else if(obj["condition"].toObject()["operator"].toObject()["code"].toString() == "<"){
                        if(diffPkgVersion(getPkgVersionFromPkgName(obj["condition"].toObject()["name"].toString()), obj["condition"].toObject()["value"].toString(), "<") == 0){
                            node = new LogicNode("true");
                        }else{
                            node = new LogicNode("false");
                        }

                    }
                    break;
                case 4:
                    if (m_productLine == obj["condition"].toObject()["value"].toString()){
                        node = new LogicNode("true");
                    }else {
                        node = new LogicNode("false");
                    }
                    break;
                case 5:
                    if (m_arch == obj["condition"].toObject()["value"].toString()){
                        node = new LogicNode("true");
                    }else {
                        node = new LogicNode("false");
                    }
                    break;
                default:
                    break;
                }

                rootNode->addChild(node);
            }else{
                LogicNode * node = new LogicNode(obj["childrenLogic"].toObject()["code"].toString());
                getChildren(obj["children"].toArray(), node);
                rootNode->addChild(node);

            }
        }else {
            return ;
        }
    }
}


